package com.gitee.wsl.compose.chart.geometry.model.pool

/*
 * Copyright 2013 Hannes Janetzek
 *
 * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
 *
 * This program is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */

abstract class Pool<T : Inlist<T>> {
    protected var mPool: T? = null
    protected var mLimit = 0
    protected var mFill = 0

    /**
     * @param item release resources
     * @return whether item should be added to
     * pool. use to manage pool size manually
     */
    protected fun clearItem(item: T): Boolean {
        return true
    }

    /**
     * Release 'item' to pool.
     *
     *
     * Usage item = pool.release(item), to ensure to not keep a reference to
     * item!
     */
    fun release(item: T): T? {
        if (item == null) return null
        if (!clearItem(item)) return null
        (item as Inlist<T>).next = mPool
        mPool = item
        return null
    }

    /**
     * Release 'list' to pool.
     *
     *
     * Usage list = pool.releaseAll(list), to ensure to not keep a reference to
     * list!
     */
    fun releaseAll(list: T): T? {
        var list: T? = list ?: return null
        while (list != null) {
            val next = list.next as T
            clearItem(list)
            (list as Inlist<T>).next = mPool
            mPool = list
            list = next
        }
        return null
    }

    /** remove 'item' from 'list' and add back to pool  */
    fun release(list: T, item: T?): T {
        if (item == null) return list
        clearItem(item)
        return Inlist.remove(list , item)
    }

    /** get an item from pool  */
    fun get(): T {
        if (mPool == null) return createItem()
        val ret  = mPool!!
        mPool = mPool!!.next as T
        ret.next = null
        return ret
    }

    protected abstract fun createItem(): T
}

